//Core
(function(){

	var YD = YAHOO.util.Dom,YE = YAHOO.util.Event;

 	YAHOO.namespace('YAHOO.Zergling');

	var zergling = function(){

		/**
		 * create a bussiness module.
		 * @class Bussiness Module 
		*/ 
		var ModuleInfo = function(){
			this.init.apply(this,arguments);
		};
		ModuleInfo.prototype = {
			/**
			 * @constructor
			 * @param {string} name 
			 * @param {object} configure
			*/
			init:function(_name,_cfg){
				/*
				 * @property {object} yuiloader
				*/
				this.loader =  new YAHOO.util.YUILoader();
				/*
				 * @property {string} module name
				*/
				this.name = _name;
				/*
				 * @property {string} creator 
				*/
				this.creator = _cfg.creator;
				/*
				 * @property {array} yui widgets
				*/
				this.require = _cfg.require || [];
				/*
				 * @property {object} debug
				*/
				this.debug = {};
				this.debug.out = YAHOO.Zergling.Configure.debug.out && _cfg.debug.out;
				this.debug.profile = YAHOO.Zergling.Configure.debug.out && _cfg.debug.profile;
				try{
					this.handler = _cfg.handler.call(this,this);
				}catch(_e){
					this.console_error(_e.message+this);
				}
			},
			/**
			 * @function use yuiload
			 */
			_loadWidgets:function(){
				this.loader.require(this.require);
				this.loader.insert();
			},
			/*
			 * @public
			 * @function format string
			 */
			toString:function(){
				var str = ['module:'+this.name,'creator:['+YAHOO.Zergling.Developer.get(this.creator).toString()+']'];
				return str.join('.');
			},
			/*
			 * @public
			 * @function fire event
			 */
			fire:function(_type,_args){
				var args = Array.prototype.slice.call(arguments, 0);  
				_type = args.shift();
				args.unshift(this);
				args.unshift(_type);
				zeventManager.fire.apply(zeventManager,args);
			},
			/*
			 * @public
			 * @function fire event
			 */
			unsubscribe:function(_type){
				if(this.handler[_type]){
					this.handler[_type] = null;
				}
			},
			console_log:function(_args){
				if(this.debug.out){
					var args = Array.prototype.slice.call(arguments, 0);  
					args.unshift(this.name+'-->log:');
					consoleAdapter.log.apply(consoleAdapter,args);
				}
			},
			console_info:function(_args){
				if(this.debug.out){
					var args = Array.prototype.slice.call(arguments, 0);  
					args.unshift(this.name+'-->info:');
					consoleAdapter.info.apply(consoleAdapter,args);
				}
			},
			console_error:function(_args){
				if(this.debug.out){
					var args = Array.prototype.slice.call(arguments, 0);  
					args.unshift(this.name+'-->error:');
					consoleAdapter.error.apply(consoleAdapter,args);
			//		this.fire('onFailure');
					this.call('onFailure',args);
				}
			},
			call:function(_type,_args){
				if(this.handler[_type]){
					var args = Array.prototype.slice.call(arguments, 0);  
					_type = args.shift();
					try{
						var _pro = new ProfileInfo(this,_type);
						_pro.start();
						this.handler[_type].apply(this,args);
						_pro.stop();
					}catch(_e){
						this.console_error(_e.message);
					}
				}
			}
		};

		var dataManager = function(){

			var _bath = (function(){
				var requests = {};
				var requests_count = 0;
				var requests_readyCount = 0;
				var responses = {};
				return {
					add:function(_url,_par){
						if(!requests[_url]){
							requests_count ++;
							requests[_url] = {};
							requests[_url].url = _url;
							requests[_url].pars = _par;
						}else{
							requests[_url].pars = requests[_url].pars + '&' + _par; 
						}
					},
					request:function(){
						for ( var req in requests ){
							var request = requests[req];
							responses[req] = {
								success:function(o){
									responses[req].data = o;
									requests_readyCount++;
									if(requests_readyCount===requests_count){
										_bath.ready(responses);
									}
								}
							};
							YAHOO.util.Connect.asyncRequest('POST',request.url,responses[req],request.pars);
						}
					},
					ready:function(){}
				};
			})();
						
			return {
				bath:_bath
			};
		};

		dataManager = dataManager();

		var moduleManager = function(){
			var modules = {};
			var modules_length=0;
			var isInit = false;
			var modules_string  = '|';
			var modules_init = 0;
			var count = {};
			count.init = 0;
			count.onPageReady = 0;
			var	callAfter = function(_name){
				var isLastOne = false;
				count[_name] = count[_name] + 1;
				if(count[_name] == YAHOO.Zergling.Configure.modules.length){
					isLastOne = true;
				}
				return isLastOne;
			};
			var init = function(){
				if(!YAHOO.Zergling.Configure){
					throw "YAHOO.Zergling.Configure not found!";
				}
				if(document.location.href.indexOf('#zergling_debug')>-1){
					YAHOO.Zergling.Configure.debug.out = true;
					YAHOO.Zergling.Configure.debug.profile= true;
				}
				modules_length = YAHOO.Zergling.Configure.modules.length;
				for(var i=0; i<modules_length; i++){
					var _name = YAHOO.Zergling.Configure.modules[i];
					modules[_name] = {};
					modules_string += _name+'|';
				}
				isInit = true;
			};
			return {
				getList:function(){
					return modules;
				},
				getListCount:function(){
					if(modules_length===0){
						modules_length = YAHOO.Zergling.Configure.modules.length;
					}
					return modules_lengt;
			  },
				getModule:function(_name){
					if(!modules[_name]){
						throw 'module not find';
					}
					return modules[_name];
				},
				send:function(_type,_args){
					var args = Array.prototype.slice.call(arguments, 0);  
					for(var m_name in modules){
						if(m_name){
							modules[m_name].call.apply(modules[m_name],args);
						}
					}
				},
				create:function(_name,_module){
					if(!isInit){
						init();
					}
					if(modules_string.indexOf('|'+_name+'|')==-1){
						return;
					}
					modules[_name] = new ModuleInfo(_name,_module);
					modules_init ++;
					if(modules_init == modules_length){
						for( var _m in modules){
							modules[_m].call('init');
						}
						moduleManager.firePageReady();
					}
				},
				firePageReady:function(){
					YE.onDOMReady(function(){
						for(var m_name in modules){
							if(m_name){
								(function(_name){
									modules[_name].loader.onSuccess = function(){
										modules[_name].call('onPageReady');
										moduleManager.firePageLoad();
									};
									modules[_name].loader.onFailure = function(){
										modules[_name].console_error('loader error');
										moduleManager.firePageLoad();
									};
									if(modules[_name].require.length===0){
										modules[_name].call('onPageReady');
										moduleManager.firePageLoad();
									}else{
										modules[_name]._loadWidgets();
									}
								})(m_name);
							}
						}
					});
				},
				firePageLoad:function(){
					if(callAfter('onPageReady')){
						for(var m_name in modules){
							if(m_name){
								modules[m_name].call('onPageLoaded');
							}
						}
						moduleManager.fireDataReady();
					}
				},
				fireDataReady:function(){
					dataManager.bath.ready = function(_responses){
						for(var m_name in modules){
							if(m_name){
								modules[m_name].call('onDataReady',_responses);
							}
						}
					};
					dataManager.bath.request();
				}
			};
		};
		moduleManager = moduleManager();




		/**
		 * create a developer
		 * @class developer 

		*/ 
		var DeveloperInfo = function(){
			this.init.apply(this,arguments);
		};
		DeveloperInfo.prototype = {
			/**
			 * @constructor
		 	 * @param {string} name 
		 	 * @param {object} configure
			 */
			init:function(_name,_cfg){
				this.name = _name;
				this.phone = _cfg.phone;
				this.email = _cfg.email;
				this.im = _cfg.im;
			},
			toString:function(){
				var str = ['name:'+this.name,'phone:'+this.phone];
				return str;
			}
		};

		var developerManager = function(){
			var developers = {};
			return {
				items:developers,
				get:function(_name){
					if(developers[_name]){
						return developers[_name];
					}else{
						return new DeveloperInfo('unknow',{phone:'unknow'});
					}
				},
				register:function(_name,_cfg){
					developers[_name] = new DeveloperInfo(_name,_cfg);
				}
			};
		};
		developerManager = developerManager();

		/*
		//äº‹ä»¶ä¿¡æ¯ç±»
		var Zevent = function(){
			this.init.apply(this,arguments);
		};
		Zevent.prototype = {
			init:function(_ce,_handler){
				this.name = _ce;
				this.handler = _handler;
			}
		};
		*/


		/**
		 * create a profile
		 * @class developer 
		*/ 
		var ProfileInfo = function(){
			this.init.apply(this,arguments);
		};
		ProfileInfo.prototype = {
			/**
			 * @constructor
			 * @param {object} ModuleInfo 
			 * @param {string} function name
			*/ 
			init:function(_module,_fun){
				this.module = _module;
				this.fun = _fun;
			},
			/*
			 * @public
			 * @function start string
			 */
			start:function(){
				this._startTime = new Date();
			},
			/*
			 * @public
			 * @function stop 
			 */
			stop:function(){
				this._endTime = new Date();
				this.time = this._endTime - this._startTime;
				profileManager.add(this);
		  },
			/*
			 * @public
			 * @function format string
			 */
			toString:function(){
				return this.module.name + '-->profile:'+this.fun+'='+this.time+'ms';
		  }
		};

		//profile
		var profileManager = function(){
			var list = [];
			return {
				getList:function(){
					return list;
				},
				add:function(_log){
					list.push(_log);
					if(_log.module.debug.profile){
						consoleAdapter.log(_log.toString());
					}
				}
			};
		};

		profileManager = profileManager();

		//event
		var zeventManager = function(){
			var events = {};
			return {
				efire:function(_type,_args){
					var args = Array.prototype.slice.call(arguments, 0);
					if(events[_type]){
						for(var i=0; i<events[_type].length;i++){
							if(events[_type][i]){
								events[_type][i].apply(events[_type][i],args);
							}
						}
					}
				},
				fire:function(_type,_args){
					var args = Array.prototype.slice.call(arguments, 0);  
					if(YAHOO.Zergling.Configure.debug.out){
						if(args.length==1){
							consoleAdapter.log('noname-->fire:'+_type);
						}else if(!!args[1].name){
							consoleAdapter.log(args[1].name+'-->fire:'+_type);
						}
					}
					moduleManager.send.apply(moduleManager,args);
					this.efire.apply(this,args);
				},
				subscribe:function(_ce,_fun){
					if(!events[_ce]){
						events[_ce] = [];
					}
					events[_ce].push(_fun);
			  }
			};
		};
		zeventManager = zeventManager();

		var consoleAdapter = function() {
			var ZERGLING_OUT = 'zergling-out';
			var isFirebug = !!(window.console && window.console.firebug);
			var htmlout = function(_args){
				for(var i=0; i<_args.length; i++){
					if(!YD.get(ZERGLING_OUT)){
						document.write('<div style="background:yellow;" id="' + ZERGLING_OUT + '"></div>');
					}
					try {
						YD.get(ZERGLING_OUT).innerHTML = YD.get(ZERGLING_OUT).innerHTML + '<p>' + _args[i]+ '</p>';
					} 
					catch (_e) {
						YE.onDOMReady(function() {
							YD.get(ZERGLING_OUT).innerHTML += _info;
						});
					}
				}
			};
			return {
				log: function(_args) {
					var args = Array.prototype.slice.call(arguments, 0);  
					if (isFirebug) {
							console.log.apply(window,args);
					}
					else {
						htmlout(args);
					}
				},
				info:function(_args){
					var args = Array.prototype.slice.call(arguments, 0);  
					if (isFirebug) {
						console.info.apply(window,args);
					}else{
						htmlout(args);
					}
			  },
				error:function(_args){
					var args = Array.prototype.slice.call(arguments, 0);  
					if (isFirebug) {
						console.error.apply(window,args);
					}else{
						htmlout(args);
					}
				}
			};
		};

		consoleAdapter = consoleAdapter();


		return {
			Version:'Alpha',
			dataManager:dataManager,
			ModuleInfo:ModuleInfo,
			Module:moduleManager,
			create:moduleManager.create,
			DeveloperInfo:DeveloperInfo,
			Developer:developerManager,
			Event:zeventManager,
			Profile:profileManager
		};
	};

	YAHOO.Zergling = zergling();

})();





